﻿using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using Hi_Baidu.Plugin;
using System.Windows.Media.Imaging;
using Hi_Baidu.Entry.CollectionObject;
using System.Text;
using WpfApplication1;
using System.Windows.Documents;
using Hi_Baidu.ProcessModel;
using Microsoft.Win32;
using Hi_Baidu.Cache.CacheObject;
using Hi_Baidu.Session;
using Hi_Baidu.ScreenShorter;
using Hi_Baidu.Hooks;
using System.Windows.Input;
using Hi_Baidu.User.LogEntry;
using Hi_Baidu.Timer.TalkMessage;
using Hi_Baidu.Enum.DigHole;
using Hi_Baidu.Cache;

namespace Hi_Baidu
{
    /// <summary>
    ///     好友聊天窗口
    /// </summary>
	public partial class Win_TalkWindow : IPopWindowAction
	{
        public static int PID = 0;
        Friend friend;
        public BitmapImage BI_Online = new BitmapImage(new Uri("pack://application:,,,/Icon/517.ico"));
        public BitmapImage BI_Offline = new BitmapImage(new Uri("pack://application:,,,/Icon/523.ico"));
        Win_Facexaml win_Face;

        public Win_TalkWindow()
        {
        }

        /// <summary>
        ///     好友聊天窗口
        /// </summary>
        /// <param name="Key">唯一标示</param>
        /// <param name="friend">好友对象</param>
		public Win_TalkWindow(String Key, Friend friend)
        {            
            WindowPlugin windowPlugin = null;
            this.InitializeComponent();
            this.friend = friend;
            this.Key = Key;
            //UDP NAT穿透
            if (friend.OnlineState)
            {
                DigHoleToFriend();
            }
            #region 加载插件部分
            ListBoxItem listBoxItem;
            foreach (Plugin.Plugin plugin in Globle.pluginManager.GetMember())
            {
                //判断插件具体类型标示
                switch (plugin.GetPluginKey())
                {
                    case Hi_Baidu.Plugin.Plugin.PLUGIN_KEY.PLUGIN_VIDEO:
                        break;
                    case Hi_Baidu.Plugin.Plugin.PLUGIN_KEY.PLUGIN_FILESHARE:
                        plugin.Tag = this.TC_Control;
                        break;
                    default:
                        break;
                }
                plugin.ForUser = Globle.user;
                //判断插件位置类型标示
                if (plugin is WindowPlugin)
                {
                    if (plugin is NetworkWindowPlugin && (plugin as NetworkWindowPlugin).Visiable == WindowPlugin.VISIABLE.Visiable && (plugin as NetworkWindowPlugin).GetPluginHost() == Hi_Baidu.Plugin.Plugin.PLUGIN_HOST.TALK_WINDOW)
                    {
                        NetworkWindowPlugin networkWindowPlugin = (plugin as NetworkWindowPlugin);
                        networkWindowPlugin.ServerIP = Hi_Baidu.ProcessModel.Model.ServerIpAddress;
                        networkWindowPlugin.ServerPort = Hi_Baidu.ProcessModel.Model.ServerPort;
                        if (networkWindowPlugin is TalkWindowNetworkWindowPlugin)
                        {
                            (networkWindowPlugin as TalkWindowNetworkWindowPlugin).RefFriend = friend;
                            (networkWindowPlugin as TalkWindowNetworkWindowPlugin).RecvMessageControl = this.rtb_ReviewMessage;
                        }
                        listBoxItem = new ListBoxItem();
                        listBoxItem.Margin = new Thickness(0, 0, 15, 0);
                        Image img = new Image();
                        img.Source = new BitmapImage(new Uri(networkWindowPlugin.PluginImagePath));
                        img.ToolTip = networkWindowPlugin.ToolTip;
                        listBoxItem.Content = img;
                        listBoxItem.Style = (Style)System.Windows.Application.Current.FindResource("Normal_ListBoxItem_Style");
                        this.ltb_Menu.Items.Add(listBoxItem);
                        networkWindowPlugin.Host = this;
                        networkWindowPlugin.Control = listBoxItem.Content as FrameworkElement;
                        //调用插件自身初始化方法
                        networkWindowPlugin.Initialize();
                        //调用插件附加事件方法
                        networkWindowPlugin.AppendEvent();
                        //加载插件网络包协议器
                        if (Packet.PackageHelper.InstallParser(networkWindowPlugin.GetNetworkProtocol(), networkWindowPlugin.GetParser()))
                        {
                            //加载插件网络包处理器
                            NetControl.processorRouter.InstallProcessor(networkWindowPlugin.GetPacketListener());
                        }
                    }
                    else if ((plugin as WindowPlugin).Visiable == WindowPlugin.VISIABLE.Visiable && (plugin as WindowPlugin).GetPluginHost() == Hi_Baidu.Plugin.Plugin.PLUGIN_HOST.TALK_WINDOW)
                    {
                        windowPlugin = (plugin as WindowPlugin);
                        listBoxItem = new ListBoxItem();
                        listBoxItem.Margin = new Thickness(0, 0, 15, 0);
                        Image img = new Image();
                        img.Source = new BitmapImage(new Uri(windowPlugin.PluginImagePath));
                        img.ToolTip = windowPlugin.ToolTip;
                        listBoxItem.Content = img;
                        listBoxItem.Style = (Style)System.Windows.Application.Current.FindResource("Normal_ListBoxItem_Style");
                        this.ltb_Menu.Items.Add(listBoxItem);
                        windowPlugin.Host = this;
                        windowPlugin.Control = listBoxItem.Content as FrameworkElement;
                        //调用插件自身初始化方法
                        windowPlugin.Initialize();
                        //调用插件附加事件方法
                        windowPlugin.AppendEvent();
                    }
                    else
                    {
                        windowPlugin = (plugin as WindowPlugin);
                        windowPlugin.Host = this;
                        //调用插件自身初始化方法
                        windowPlugin.Initialize();
                        //调用插件附加事件方法
                        windowPlugin.AppendEvent();
                    }
                }
                else if (plugin is NetworkPlugin)
                {
                    NetworkPlugin netkPlugin = (plugin as NetworkPlugin);
                    //调用插件自身初始化方法
                    netkPlugin.Initialize();
                    //加载插件网络包协议器
                    if (Packet.PackageHelper.InstallParser(netkPlugin.GetNetworkProtocol(), netkPlugin.GetParser()))
                    {
                        //加载插件网络包处理器
                        NetControl.processorRouter.InstallProcessor(netkPlugin.GetPacketListener());
                    }
                }
            }

            #endregion
           
            //好友备注
            TYPE_UserMark userMark = Globle.userMarkManager.GetMemberByKey(friend.Username) as TYPE_UserMark;
            if (userMark != null)
            {
                this.tb_NickName.Text = userMark.MarkName;
            }
            else
            {
                this.tb_NickName.Text = friend.Name;
            }
            this.tb_Prod.Text = friend.Prod;
            this.Img_OnlineState.Source = friend.OnlineState == true ? BI_Online : BI_Offline;
            this.FHIC_Friend.Username = friend.Name;
            this.FHIC_Friend.HeadImagePath = friend.HeadImageName;
            this.FHIC_MySelf.Username = Encoding.Default.GetString(Globle.user.DIC_USERINFO["NICKNAME"]);
            this.FHIC_MySelf.HeadImagePath = Encoding.Default.GetString(Globle.user.DIC_USERINFO["HEADIMAGE"]);
            this.FHIC_Friend.Init();
            this.FHIC_MySelf.Init();
            this.Title = friend.Name;
            win_Face = new Win_Facexaml();
            win_Face.OnUserSelectFace += new EventHandler<Win_Facexaml.OnUserSelectFaceEventArgs>(win_Face_OnUserSelectFace);
            InitFontName();
            this.cbx_FontCollection.SelectionChanged+=new SelectionChangedEventHandler(cbx_FontCollection_SelectionChanged);
            this.cbx_FontSize.SelectionChanged+=new SelectionChangedEventHandler(cbx_FontSize_SelectionChanged);
        }


        #region UDP打洞部分

        public void DigHoleToFriend()
        {
            if (!this.friend.HasTalkPortHole && this.friend.OnlineState)
            {
                friend.DigHole
                    (
                        Globle.user.DIC_USERINFO["USERNAME"],
                        BitConverter.GetBytes(Globle.user.TALK_PORT),
                        (int)DigType.TALK,
                        Globle.user.SESSION_CODE,
                        Hi_Baidu.ProcessModel.Model.ServerIpAddress,
                        Hi_Baidu.ProcessModel.Model.ServerPort
                    );
            }
            if (!this.friend.HasFilePortHole && this.friend.OnlineState)
            {
                friend.DigHole
                    (
                        Globle.user.DIC_USERINFO["USERNAME"],
                        BitConverter.GetBytes(Globle.user.TRANSFER_FILE_PORT),
                        (int)DigType.FILE_TRANSFER,
                        Globle.user.SESSION_CODE,
                        Hi_Baidu.ProcessModel.Model.ServerIpAddress,
                        Hi_Baidu.ProcessModel.Model.ServerPort
                    );
            }
        }

        #endregion

        /// <summary>
        ///     初始化字体
        /// </summary>
        private void InitFontName()
        {
            System.Drawing.FontFamily[] MyFamilies = System.Drawing.FontFamily.Families;
            foreach (System.Drawing.FontFamily MyFamily in MyFamilies)
            {
                this.cbx_FontCollection.Items.Add(MyFamily.Name);
            }
            //初始化字体大小
            for (int i = 8; i < 22; i++)
            {
                this.cbx_FontSize.Items.Add(i);
            }
        }

        void win_Face_OnUserSelectFace(object sender, Win_Facexaml.OnUserSelectFaceEventArgs e)
        {
            ImageExpender Img_Exp = new ImageExpender();
            Img_Exp.Stretch = Stretch.None;
            Img_Exp.Visibility = Visibility.Visible;
            Stream imageStream = System.Windows.Application.GetResourceStream(new Uri(@"sysface/" + e.Face_Path, UriKind.Relative)).Stream;
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(imageStream);
            Img_Exp.Image = bitmap;
            Img_Exp.Location = "../sysface/" + e.Face_Path;
            Img_Exp.ToolTip = "../sysface/" + e.Face_Path;
            Img_Exp.Tag = "../sysface/" + e.Face_Path;

            InlineUIContainer IUC = new InlineUIContainer();
            IUC.Child = Img_Exp;
            Paragraph paragraph = new Paragraph(IUC);
            this.rtb_TalkMessage.Document.Blocks.Add(paragraph);
        }

        private void Window_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
            {
                try
                {
                    this.DragMove();
                }
                catch { }
            }
        }

        #region IPopWindowAction 成员

        public void DisposeToManager()
        {
            Globle.popWindowManager.Remove(this.key);
        }

        #endregion

        #region IMetaData 成员

        private String key;
        public string Key
        {
            get
            {
                return key;
            }
            set
            {
                key = value;
            }
        }

        #endregion

        private void Window_Closed(object sender, EventArgs e)
        {
            this.DisposeToManager();
        }

        private void Img_Font_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (this.BD_FontSetting.Visibility == Visibility.Collapsed)
            {
                this.BD_FontSetting.Visibility = Visibility.Visible;
            }
            else
            {
                this.BD_FontSetting.Visibility = Visibility.Collapsed;
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //如果当前好友未在线，则提示下 o(∩_∩)o...哈哈
            if (!this.friend.OnlineState)
            {
                if (this.BD_NotifyInfo.Visibility == Visibility.Collapsed)
                {
                    this.tb_NotifyText.Text = "对方当前不在线或隐身，可能无法立即回复。";
                    this.BD_NotifyInfo.Visibility = Visibility.Visible;
                }
            }
        }

        private void Img_CloseNotify_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (this.BD_NotifyInfo.Visibility == Visibility.Visible)
            {
                this.BD_NotifyInfo.Visibility = Visibility.Collapsed;
            }
        }

        private void Img_Biaoqing_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (this.win_Face != null && this.win_Face.Visibility == Visibility.Collapsed)
            {
                Point WP = (sender as Image).PointToScreen(new Point(0, 0));
                this.win_Face.Left = WP.X;
                this.win_Face.Top = WP.Y - this.win_Face.Height;
                this.win_Face.Show();
            }
            else if (this.win_Face.Visibility == Visibility.Visible)
            {
                this.win_Face.Visibility = Visibility.Collapsed;
            }
        }

        private void btn_Send_Click(object sender, RoutedEventArgs e)
        {
            SendMessage();
        }

        /// <summary>
        ///     发送消息
        /// </summary>
        private void SendMessage()
        {
            String XML_Content = ChatProcessModel.Construe(this.rtb_TalkMessage, ref PID);
            if (XML_Content != "")
            {
                ChatProcessModel.SendTalkMessage(XML_Content, Encoding.Default.GetString(Globle.user.DIC_USERINFO["USERNAME"]), this.friend);
                ChatViewModel.AppendForMySelf(this.rtb_TalkMessage, this.friend.Username);
                this.rtb_TalkMessage.Document.Blocks.Clear();
            }
        }

        private void Img_SendPic_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            OpenFileDialog OFD = new OpenFileDialog();
            OFD.Title = "请选择要发送的图片";
            OFD.Filter = "JPG 图片文件|*.jpg|GIF 动画文件|*.gif";
            OFD.Multiselect = false;
            if ((bool)OFD.ShowDialog())
            {
                String POP_PICTURE_CODE = EncryptHashHelper.HashString("POP-PIC:" + DateTime.Now.ToString());
                //创建提取图片缓存
                PopPictureCache popPictureCache = new PopPictureCache(POP_PICTURE_CODE, OFD.FileName, DateTime.Now.AddMinutes(1), PopPictureCache.PopType.File);
                String[] DateChunk = OFD.SafeFileName.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries);
                popPictureCache.Ext = DateChunk[DateChunk.Length - 1];
                //打入提取图片缓存
                DeclareCacheManager.popPictureCacheManager.Add(popPictureCache);
                String FileName = OFD.SafeFileName;
                if (FileName != null)
                {
                    String[] FileChunk = FileName.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries);
                    switch (FileChunk[FileChunk.Length - 1].ToLower())
                    {
                        //JPG 图片文件
                        case "jpg":
                            Image img = img = new Image();
                            img.Source = new BitmapImage(new Uri(OFD.FileName, UriKind.Absolute));
                            img.Tag = POP_PICTURE_CODE;
                            img.ToolTip = OFD.FileName;
                            ChatViewModel.AppendImage(this, img);
                            break;
                        //GIF 动画文件
                        case "gif":
                            ImageExpender img_Ex = new ImageExpender();
                            img_Ex.Stretch = Stretch.None;
                            using(FileStream fs = new FileStream(OFD.FileName, FileMode.Open, FileAccess.Read))
                            {
                                Stream imageStream = fs;
                                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(imageStream);
                                img_Ex.Image = bitmap;
                                img_Ex.Location = OFD.FileName;
                                img_Ex.ToolTip = OFD.FileName;
                                img_Ex.Tag = POP_PICTURE_CODE;
                                ChatViewModel.AppendGif(this, img_Ex);
                            }
                            break;
                    }
                }
            }
        }

        private void Img_ScreenShot_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Win_Shortcut win_Shortcut = new Win_Shortcut();
            win_Shortcut.OnGetImage += new EventHandler<Win_Shortcut.OnGetImageEventArgs>(win_Shortcut_OnGetImage);
            win_Shortcut.Show();
        }

        void win_Shortcut_OnGetImage(object sender, Win_Shortcut.OnGetImageEventArgs e)
        {
            String POP_PICTURE_CODE = EncryptHashHelper.HashString("POP-PIC:" + DateTime.Now.ToString());
            //创建提取图片缓存
            PopPictureCache popPictureCache = new PopPictureCache(POP_PICTURE_CODE, null, DateTime.Now.AddMinutes(1), PopPictureCache.PopType.Stream);
            popPictureCache.PictureStream = e.ScreenImage;
            //打入提取图片缓存
            DeclareCacheManager.popPictureCacheManager.Add(popPictureCache);
            ImageExpender img_Ex = new ImageExpender();
            img_Ex.Image = e.ScreenImage;
            img_Ex.Stretch = Stretch.None;
            img_Ex.Width = e.ScreenImage.Width;
            img_Ex.Height = e.ScreenImage.Height;
            img_Ex.Tag = POP_PICTURE_CODE;
            img_Ex.ToolTip = POP_PICTURE_CODE;
            img_Ex.Visibility = Visibility.Visible;
            InlineUIContainer IUC = new InlineUIContainer();
            IUC.Child = img_Ex;
            Paragraph paragraph = new Paragraph(IUC);
            this.rtb_TalkMessage.Document.Blocks.Add(paragraph);
        }

        private void cbx_FontCollection_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //变更当前聊天框字体
            if(this.cbx_FontCollection.SelectedItem != null)
            {
                this.rtb_TalkMessage.FontFamily = new FontFamily(this.cbx_FontCollection.SelectedItem.ToString());
            }
        }

        private void cbx_FontSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if(this.cbx_FontSize.SelectedItem != null)
            {
                this.rtb_TalkMessage.FontSize = (int)this.cbx_FontSize.SelectedItem;
            }
        }

        private void Img_Clock_MouseDown(object sender, MouseButtonEventArgs e)
        {
            //当前好友不在线
            if (!friend.OnlineState)
            {
                ChatViewModel.AppendSendShadowFail(friend);
            }
            //在线
            else
            {
                ChatProcessModel.SendWindowShadow(Globle.user.DIC_USERINFO["USERNAME"], friend);
            }
        }

        private void ToggleButton_Checked(object sender, RoutedEventArgs e)
        {

        }
    }
}